/**
 * tinymce 工具函数
 * 无状态函数、可移植
 */
import { katexSanitize } from './katex'
/* eslint-disable */

const root = typeof window !== 'undefined' ? window : global
export const Tinymce = root && 'tinymce' in root ? root.tinymce : null

export const uuid = prefix => {
  return prefix + '_' + (Date.now() + Math.floor(Math.random() * 1000000))
}

const restoreTex = html => {
  let latexStart = html.indexOf('<tag-tex')
  let latex = ''
  while (latexStart >= 0) {
    let latexEnd = html.indexOf('</tag-tex>') + 10
    let latexTag = html.substring(latexStart, latexEnd)
    let latexArr = latexTag.match(/data-latex="(.*?)"/g)
    if (latexArr) {
      latex = latexArr[0]
      latex = latex.replace(/^(data-latex=")|"$/g, '')
    }
    latex = latex.replace(/\s*&amp;\s*(?!\w)/g, ' & ')
    html = html.replace(latexTag, `<tex data-latex="${latex}"></tex>`)
    latexStart = html.indexOf('<tag-tex')
  }
  return html
}

const restoreBlk = html => {
  let blkStart = html.indexOf('<tag-blk')
  while (blkStart >= 0) {
    let blkEnd = html.indexOf('</tag-blk>') + 10
    let blkTag = html.substring(blkStart, blkEnd)
    let mlenStr = '',
      markStr = '',
      mstyleStr = '',
      dataIndexStr = ''
    let mlenArr = blkTag.match(/mlen="(.*?)"/g)
    if (mlenArr) {
      mlenStr = mlenArr[0]
    }
    let markArr = blkTag.match(/mark="(.*?)"/g)
    if (markArr) {
      markStr = markArr[0]
    }
    let mstyleArr = blkTag.match(/mstyle="(.*?)"/g)
    if (mstyleArr) {
      mstyleStr = mstyleArr[0]
    }
    let dataIndexArr = blkTag.match(/data-index="(.*?)"/g)
    if (dataIndexArr) {
      dataIndexStr = dataIndexArr[0]
    }
    html = html.replace(
      blkTag,
      `<blk ${mlenStr} ${markStr} ${mstyleStr} ${dataIndexStr}>&nbsp;</blk>`
    )
    blkStart = html.indexOf('<tag-blk')
  }
  return html
}

const restoreAudio = html => {
  let audioStart = html.indexOf('<tag-audio')
  while (audioStart >= 0) {
    let audioEnd = html.indexOf('</tag-audio>') + 12
    let audioTag = html.substring(audioStart, audioEnd)
    let srcArr = audioTag.match(/\s+src="(.*?)"/g)
    let src = ''
    let typeStr = ''
    if (srcArr) {
      src = srcArr[0]
      if (/\.mp3/gi.test(src)) {
        typeStr = 'type="audio/mpeg"'
      } else if (/\.ogg/gi.test(src)) {
        typeStr = 'type="audio/ogg"'
      } else if (/\.wav/gi.test(src)) {
        typeStr = 'type="audio/wav"'
      }
    }
    html = html.replace(audioTag, `<audio ${src} ${typeStr}>&nbsp;</audio>`)
    audioStart = html.indexOf('<tag-audio')
  }
  return html
}

const restoreImage = content => {
  if (typeof content !== 'string') return content
  const domain = 'https://contres.readboy.com'
  let imgReg = /<img.*?(?:>|\/>)/gi
  let srcReg = /src=[\'\"]?([^\'\"]*)[\'\"]?/i
  let arr = content.match(imgReg) // arr 为包含所有img标签的数组
  arr?.forEach(item => {
    let srcMatch = item.match(srcReg)
    if (srcMatch?.[1]) {
      let src = srcMatch[1]
      src = src.replace(domain, '')
      let str = item.replace(srcMatch[1], src)
      content = content.replace(item, str)
    }
  })
  return content
}

//@param: html-已渲染的html文本
export const restoreHtml = html => {
  html = restoreImage(html)
  html = restoreAudio(html)
  if (html.match(/<(tag-blk|tag-tex|tag-audio)\s/g)) {
    // tag-tex => tex
    html = restoreTex(html)
    // tag-blk => blk
    html = restoreBlk(html)
  }
  //去除两端和中间空格
  html = html = html.replace(
    /(&nbsp;|\s)?<blk(.*?)>.*?<\/blk>(&nbsp;|\s)?/g,
    '<blk$2></blk>'
  )
  html = html.replace(
    /(&nbsp;|\s)?<tex(.*?)>.*?<\/tex>(&nbsp;|\s)?/g,
    '<tex$2></tex>'
  )
  html = html.replace(
    /(&nbsp;|\s)?<audio(.*?)>.*?<\/audio>(&nbsp;|\s)?/g,
    '<audio$2></audio>'
  )

  return html
}

export const formatHtml = html => {
  // 将富文本加工处理成可视化（公式/填空位/图片等）
  let v = html.replace(/tag-blk/g, 'blk')
  v = v.replace(/tag-tex/g, 'tex')
  v = katexSanitize(v, 2)
  return v
}

export function hasClass(element, cls) {
  if (element) {
    return ('' + element.className + '').indexOf('' + cls + '') > -1
  } else {
    return false
  }
}

function findElement(target, tagName, containerClass) {
  if (
    target?.parentNode &&
    target?.tagName !== tagName.toUpperCase() &&
    !hasClass(target?.parentNode, containerClass)
  ) {
    return findElement(target?.parentNode, tagName, containerClass)
  } else if (target?.tagName === tagName.toUpperCase()) {
    return target
  } else {
    return null
  }
}

//查找父节点tag-tex
export function findTagTex(element, targetClass) {
  return findElement(element, 'tag-tex', targetClass)
}
//查找父节点tag-blk
export function findTagBlk(element, targetClass) {
  return findElement(element, 'tag-blk', targetClass)
}
/**
 * 获得字符串实际长度，中文2，英文1
 * @param str 要获得长度的字符串
 * @param mode 模式：1 下划线填空长度 2 括号填空长度
 * @returns { number }长度
 */
const getLength = function (str, mode = 1) {
  if (mode === 1) {
    let realLength = 0,
      len = str.length,
      charCode = -1
    for (let i = 0; i < len; i++) {
      charCode = str.charCodeAt(i)
      if (charCode >= 0 && charCode <= 128) {
        realLength += 1
      } else {
        realLength += 2
      }
    }
    return realLength
  }
  return (str.match(/ /g)?.length || 0) * 2 || 3
}
/**
 *
 * @param {string} str 要替换填空位的富文本字符串
 * @param {number} mode 替换模式 1 替换所有下划线填空位  2 替换所有括号填空位
 * @returns
 */
export const fillBlank = function (str, mode = 1) {
  let content = str
  if (mode == 2) {
    // 中文括号里面空格
    let blkArray = content.match(/（(\s|&nbsp;)*）/g)
    if (blkArray) {
      blkArray.forEach(val => {
        let formatVal = val.replace(/（|）/g, '')
        let len = getLength(formatVal, 2)
        if (len <= 3) {
          len = 3
        }
        let blk = '（<blk mlen="' + len + '"></blk>）'
        let reg = eval('/' + val + '/g')
        content = content.replace(reg, blk)
      })
    }
    // 英文括号里面空格
    blkArray = content.match(/\((\s|&nbsp;)*\)/g)
    if (blkArray) {
      blkArray.forEach(val => {
        let formatVal = val.replace(/\(|\)/g, '')
        let len = getLength(formatVal, 2)
        if (len <= 3) {
          len = 3
        }
        let blk = '（<blk mlen="' + len + '"></blk>）'
        content = content.replace(val, blk)
      })
    }
  } else {
    //带下划线空格
    let blkArray = content.match(/<u[^>]*?>(\s|&nbsp;)+<\/u>/g)
    if (blkArray) {
      blkArray.forEach(val => {
        let formatVal = val.replace(/<u[^>]*?>|<\/u>/g, '')
        val = val.replace(/\//g, '\\/')
        let len = getLength(formatVal)
        let blk = '<blk mlen="' + len + '" mstyle="underline">&nbsp;</blk>'
        let reg = eval('/' + val + '/g')
        content = content.replace(reg, blk)
      })
    }
    //手打下滑线
    blkArray = content.match(/_{2,}/g)
    if (blkArray) {
      blkArray.forEach(val => {
        val = val.replace(/\//g, '\\/')
        let len = getLength(val)
        let blk = '<blk mlen="' + len + '"  mstyle="underline">&nbsp;</blk>'
        let reg = eval('/' + val + '/g')
        content = content.replace(reg, blk)
      })
    }
  }
  return content
}
